package com.gioneco.util.esCondition;

import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.query.FetchSourceFilter;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * 构建 ES条件
 * @author dongjialin
 * @since 2022-06-01
 */
public class EntityEtlBuilder {

    /**
     * ES 语句构建
     */
    public NativeSearchQueryBuilder dslHandler(Criteria criteria) {
        NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
        BoolQueryBuilder boolQueryBuilder = new BoolQueryBuilder();
        List<SortBuilder> sortBuilders = null;
        Pageable pageable = null;
        //判断必要条件是否为空
        if(!CollectionUtils.isEmpty(criteria.mustParamMap)){
            mustConditionHandler(criteria.mustParamMap,boolQueryBuilder);
        }
        //模糊匹配条件
        if(!CollectionUtils.isEmpty(criteria.likeParamMap)){
            likeConditionHandler(criteria.likeParamMap,boolQueryBuilder);
        }
        if(!CollectionUtils.isEmpty(criteria.orderParamMap)){
            sortBuilders = orderConditionHandler(criteria.orderParamMap);
        }
        if(!CollectionUtils.isEmpty(criteria.pagerParamMap)){
            pageable = pageConditionHandler(criteria.pagerParamMap);
        }
        if(!CollectionUtils.isEmpty(criteria.withFieldsParamSet)){
            queryBuilder.withFields(criteria.withFieldsParamSet.toArray(new String[0]));
        }

        if(!ObjectUtils.isEmpty(criteria.rangeQueryBuilder)){
            boolQueryBuilder.must(criteria.rangeQueryBuilder);
        }

        if(!ObjectUtils.isEmpty(criteria.aggregationBuilder)){
            queryBuilder.addAggregation(criteria.aggregationBuilder);
            //统计无需返回字段
            queryBuilder.withSourceFilter(new FetchSourceFilter(new String[]{""}, null));
        }

        if(!ObjectUtils.isEmpty(boolQueryBuilder) && criteria.aggregationBuilder == null){
            queryBuilder.withFilter(boolQueryBuilder);
        }else {
            queryBuilder.withQuery(boolQueryBuilder);
        }
        if(!CollectionUtils.isEmpty(sortBuilders)){
            sortBuilders.forEach(queryBuilder::withSort);
        }
        if(!ObjectUtils.isEmpty(pageable)){
            queryBuilder.withPageable(pageable);
        }
        return queryBuilder;
    }

    private BoolQueryBuilder likeConditionHandler(Map<String, Object> likeParamMap,BoolQueryBuilder boolQueryBuilder) {
        Iterator<Map.Entry<String, Object>> iterator = likeParamMap.entrySet().iterator();
        while (iterator.hasNext()){
            Map.Entry<String, Object> next = iterator.next();
            String key = next.getKey();
            Object value = next.getValue();
            boolQueryBuilder.must(QueryBuilders.wildcardQuery(key + ".keyword","*" + value.toString() + "*"));
        }
        return boolQueryBuilder;
    }


    /**
     * 分页条件处理
     */
    private Pageable pageConditionHandler(Map<String, Object> pagerParamMap) {
        return PageRequest.of((int) pagerParamMap.get("current"), (int) pagerParamMap.get("size"));
    }

    /**
     * 排序条件处理
     */
    private List<SortBuilder> orderConditionHandler(Map<String, Object> orderParamMap) {
        List<SortBuilder> sortBuilders = new ArrayList<>();
        Iterator<Map.Entry<String, Object>> iterator = orderParamMap.entrySet().iterator();
        while (iterator.hasNext()){
            Map.Entry<String, Object> next = iterator.next();
            String key = next.getKey();
            Object value = next.getValue();
            sortBuilders.add(SortBuilders.fieldSort(key).order((SortOrder) value));
        }
        return sortBuilders;
    }

    /**
     * 必要条件的处理
     */
    private BoolQueryBuilder mustConditionHandler(Map<String, Object> mustParamMap,BoolQueryBuilder boolQueryBuilder) {
        Iterator<Map.Entry<String, Object>> iterator = mustParamMap.entrySet().iterator();
        while (iterator.hasNext()){
            Map.Entry<String, Object> next = iterator.next();
            String key = next.getKey();
            Object value = next.getValue();
            boolQueryBuilder.must(QueryBuilders.termQuery(key,value));
        }
        return boolQueryBuilder;
    }
}
